package cn.zhxu.toys.oss;

import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Random;

/**
 * MinIO 对象存储管理器（兼容 AWS S3）
 * @author Troy.Zhou
 */
public class MinioOssManager extends AbstractOssManager implements InitializingBean, DisposableBean {

	private String accessKeyId;
	private String accessKeySecret;
    private String region;
	private String bucketName;
    private boolean forcePathStyle = true;

	private transient MinioClient client;

	@Override
	public void afterPropertiesSet() {
        client = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKeyId, accessKeySecret)
                .build();
	}

	@Override
	public InputStream access(String key) {
        try {
            return client.getObject(GetObjectArgs.builder().bucket(bucketName).object(key).build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

	@Override
	public String upload(String fileName, String key, String contentType, String extension, InputStream inputStream) {
		try {
			long fileSize = inputStream.available();
			if(fileSize > maxSize) {
				inputStream.close();
				throw new RuntimeException("上传的文件过大：" + fileSize + "，最大只允许：" + maxSize);
			}
			if (fileName == null) {
				fileName = System.currentTimeMillis() + new Random().nextInt() + extension;
			} else {
				fileName += extension;
			}
			if (!key.endsWith("/")) {
				key += "/";
			}
			String fileKey = key + fileName;
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileKey)
                    .contentType(contentType)
                    .stream(inputStream, fileSize, -1)
                    .build();
            client.putObject(args);
			return resolveFileAccessUrl(fileKey);
		} catch (Exception e) {
			throw new RuntimeException("上传出现异常：" + e.getMessage(), e);
		}
	}

	@Override
	public boolean delete(String fileUrl) {
		String fileKey = resolveFileKey(fileUrl);
		if (fileKey == null) {
            return false;
        }
        String decodedKey = URLDecoder.decode(fileKey, StandardCharsets.UTF_8);
        try {
            client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(decodedKey).build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return true;
	}

	@Override
	public void destroy() throws Exception {
		client.close();
	}

	@Override
	protected String getBaseAccessUrl(String protocol, String host) {
		return protocol + host + "/" + bucketName + "/";
	}

	public String getAccessKeyId() {
		return accessKeyId;
	}

	public void setAccessKeyId(String accessKeyId) {
		this.accessKeyId = accessKeyId;
	}

	public String getAccessKeySecret() {
		return accessKeySecret;
	}

	public void setAccessKeySecret(String accessKeySecret) {
		this.accessKeySecret = accessKeySecret;
	}

	public String getBucketName() {
		return bucketName;
	}

	public void setBucketName(String bucketName) {
		this.bucketName = bucketName;
	}

    public boolean isForcePathStyle() {
        return forcePathStyle;
    }

    public void setForcePathStyle(boolean forcePathStyle) {
        this.forcePathStyle = forcePathStyle;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

}
